const { Sequelize } = require('sequelize');
const path = require('path');
const fs = require('fs');
const { sequelize } = require('../dao/dbConnect');

/**
 * 数据库迁移管理器
 */
class MigrationManager {
  constructor() {
    this.migrationsPath = path.join(__dirname, 'migrations');
    this.migrationTableName = 'sequelize_meta';
  }

  /**
   * 创建迁移记录表
   */
  async createMigrationTable() {
    const [results] = await sequelize.query(`
      CREATE TABLE IF NOT EXISTS ${this.migrationTableName} (
        name VARCHAR(255) NOT NULL PRIMARY KEY
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
    `);
    return results;
  }

  /**
   * 获取已执行的迁移
   */
  async getExecutedMigrations() {
    try {
      const [results] = await sequelize.query(
        `SELECT name FROM ${this.migrationTableName} ORDER BY name`
      );
      return results.map(row => row.name);
    } catch (error) {
      // 如果表不存在，返回空数组
      if (error.original && error.original.code === 'ER_NO_SUCH_TABLE') {
        return [];
      }
      throw error;
    }
  }

  /**
   * 获取所有迁移文件
   */
  getPendingMigrations() {
    if (!fs.existsSync(this.migrationsPath)) {
      console.log('⚠️  迁移目录不存在');
      return [];
    }

    const files = fs.readdirSync(this.migrationsPath)
      .filter(file => file.endsWith('.js'))
      .sort();

    return files;
  }

  /**
   * 记录已执行的迁移
   */
  async recordMigration(migrationName) {
    await sequelize.query(
      `INSERT INTO ${this.migrationTableName} (name) VALUES (?)`,
      {
        replacements: [migrationName],
        type: Sequelize.QueryTypes.INSERT
      }
    );
  }

  /**
   * 移除迁移记录
   */
  async removeMigrationRecord(migrationName) {
    await sequelize.query(
      `DELETE FROM ${this.migrationTableName} WHERE name = ?`,
      {
        replacements: [migrationName],
        type: Sequelize.QueryTypes.DELETE
      }
    );
  }

  /**
   * 执行单个迁移
   */
  async runMigration(migrationFile, direction = 'up') {
    const migrationPath = path.join(this.migrationsPath, migrationFile);
    
    if (!fs.existsSync(migrationPath)) {
      throw new Error(`迁移文件不存在: ${migrationFile}`);
    }

    console.log(`${direction === 'up' ? '⬆️' : '⬇️'} 执行迁移: ${migrationFile}`);

    try {
      const migration = require(migrationPath);
      
      if (typeof migration[direction] !== 'function') {
        throw new Error(`迁移文件 ${migrationFile} 缺少 ${direction} 方法`);
      }

      // 执行迁移
      await migration[direction](sequelize.getQueryInterface(), Sequelize);

      if (direction === 'up') {
        await this.recordMigration(migrationFile);
        console.log(`✅ 迁移成功: ${migrationFile}`);
      } else {
        await this.removeMigrationRecord(migrationFile);
        console.log(`✅ 回滚成功: ${migrationFile}`);
      }

    } catch (error) {
      console.error(`❌ 迁移失败: ${migrationFile}`);
      console.error(error.message);
      throw error;
    }
  }

  /**
   * 执行所有待执行的迁移
   */
  async migrate() {
    console.log('🚀 开始执行数据库迁移...');
    console.log('='.repeat(50));

    try {
      // 创建迁移记录表
      await this.createMigrationTable();

      // 获取已执行和待执行的迁移
      const executedMigrations = await this.getExecutedMigrations();
      const allMigrations = this.getPendingMigrations();
      
      const pendingMigrations = allMigrations.filter(
        migration => !executedMigrations.includes(migration)
      );

      if (pendingMigrations.length === 0) {
        console.log('✅ 没有待执行的迁移');
        return;
      }

      console.log(`📋 发现 ${pendingMigrations.length} 个待执行的迁移:`);
      pendingMigrations.forEach(migration => {
        console.log(`   - ${migration}`);
      });
      console.log('');

      // 执行迁移
      for (const migration of pendingMigrations) {
        await this.runMigration(migration, 'up');
      }

      console.log('='.repeat(50));
      console.log('🎉 所有迁移执行完成！');

    } catch (error) {
      console.error('💥 迁移执行失败:', error.message);
      throw error;
    }
  }

  /**
   * 回滚最后一个迁移
   */
  async rollback() {
    console.log('🔄 开始回滚最后一个迁移...');

    try {
      const executedMigrations = await this.getExecutedMigrations();
      
      if (executedMigrations.length === 0) {
        console.log('⚠️  没有可回滚的迁移');
        return;
      }

      const lastMigration = executedMigrations[executedMigrations.length - 1];
      await this.runMigration(lastMigration, 'down');

      console.log('✅ 回滚完成');

    } catch (error) {
      console.error('❌ 回滚失败:', error.message);
      throw error;
    }
  }

  /**
   * 显示迁移状态
   */
  async status() {
    console.log('📊 迁移状态:');
    console.log('='.repeat(50));

    try {
      await this.createMigrationTable();
      
      const executedMigrations = await this.getExecutedMigrations();
      const allMigrations = this.getPendingMigrations();

      console.log('已执行的迁移:');
      if (executedMigrations.length === 0) {
        console.log('   (无)');
      } else {
        executedMigrations.forEach(migration => {
          console.log(`   ✅ ${migration}`);
        });
      }

      console.log('\n待执行的迁移:');
      const pendingMigrations = allMigrations.filter(
        migration => !executedMigrations.includes(migration)
      );
      
      if (pendingMigrations.length === 0) {
        console.log('   (无)');
      } else {
        pendingMigrations.forEach(migration => {
          console.log(`   ⏳ ${migration}`);
        });
      }

    } catch (error) {
      console.error('❌ 获取迁移状态失败:', error.message);
      throw error;
    }
  }
}

/**
 * 命令行处理
 */
async function main() {
  const manager = new MigrationManager();
  const command = process.argv[2] || 'migrate';

  try {
    switch (command) {
      case 'migrate':
      case 'up':
        await manager.migrate();
        break;
      
      case 'rollback':
      case 'down':
        await manager.rollback();
        break;
      
      case 'status':
        await manager.status();
        break;
      
      default:
        console.log('用法:');
        console.log('  node migrate.js migrate   # 执行所有待执行的迁移');
        console.log('  node migrate.js rollback  # 回滚最后一个迁移');
        console.log('  node migrate.js status    # 显示迁移状态');
        process.exit(1);
    }

  } catch (error) {
    console.error('💥 操作失败:', error.message);
    process.exit(1);
  } finally {
    await sequelize.close();
    console.log('🔌 数据库连接已关闭');
  }
}

// 如果直接运行此脚本
if (require.main === module) {
  main();
}

module.exports = MigrationManager;
